//#include "exam.h"
#include <QCoreApplication>
#include <qprocess.h>
#include <qfileinfo.h>
#include <qdebug.h>
#include <stdio.h>
#include <iostream>
#include <QFile>

using namespace std;

/**
 *
 * -------------------------------------------------------------------------------------------------------------------
 * 题目
 * -------------------------------------------------------------------------------------------------------------------
 *
 * 遵循 https://specifications.freedesktop.org/desktop-entry-spec/latest/ 标准实现一个desktop文件解析工具
 *
 * 功能要求
 * - desktop文件格式无错误时进程退出码为0
 * - 实现对desktop文件Name(程序名称)、Exec(可执行文件)、Icon(图标文件)三个字段的解析
 * - 需要检测文件的格式，遇到错误时以退出码 1 退出进程
 * - 输入接收一个desktop文件的绝对路径，能够输出程序名称、图标文件（图标文件不考虑从系统图标主题中查找）
 * - 能够在指定一个desktop文件后启动进程，且允许为其指定参数
 *
 * 其它要求
 * - 使用cmake构建工程
 * - 可执行文件位置和名称为：./src/freedesktop
 *
 * 示例
 * - a.desktop文件内容为:
 *     [Desktop Entry]
 *     Name=A;
 *     Name[zh_CN]="我是A";
 *     Exec=cat %f
 *     Icon=/tmp/a.png
 *
 * - 输入参数（-d指定desktop文件的绝对路径，-n表示要获取应用程序名称）：
 *     freedesktop -d /home/a/a.desktop -n
 * - 输出结果：
 *     A或我是A（中文环境下，注意应该去掉引号）
 *
 * - 输入参数（-i表示要获取应用程序的图标）
 *     freedesktop -d /home/a/a.desktop -i
 * - 输出结果（如图标数据不是一个文件路径，则先将图标文件保存为文件后再返回此文件的绝对路径）：
 *     /tmp/a.png
 *
 * - 输入参数（-e表示要启动此应用程序，其后可根一个或多个传入参数）
 *     freedesktop -d /home/a/a.desktop -e /home/a/test.txt
 * - 输出结果：
 *     输出结果为 /home/a/test.txt 文件的内容，也就是Exec命令执行时对标准输出通道所写入的全部数据
 *
 */

int checkFile(QString fileName)
{
    int flag = 0;
    QFile file(fileName);
    if (file.open(QIODevice::ReadOnly)) {
        QString str = file.readAll().trimmed();
        QStringList lst = str.split('\n');
        for (int i = 0; i < lst.count(); i++) {
            if (i == 0) {
                QString data = lst.at(i);
                if (data.startsWith("[") && data.endsWith("]")) {
                    continue;
                } else {
                    flag = -1;
                    break;
                }
            } else {
                QString data = lst.at(i);
                QStringList lstData = data.split("=");
                if (lstData.count() != 2) {
                    flag = -1;
                    break;
                }
            }
        }
    }

    file.close();

    return flag;
}

QString getName(QString fileName)
{
    QString name = "";
    QFile file(fileName);
    if (file.open(QIODevice::ReadOnly)) {
        QString str = file.readAll().trimmed();
        QStringList lst = str.split('\n');
        for (int i = 0; i < lst.count(); i++) {
            QString data = lst.at(i);
            if (data.contains("Name")) {
                QStringList lstData = data.split("=");
                name = lstData.at(1);
                name.remove(";");
                break;
            }
        }
    }

    file.close();
    return name;
}

QString getIcon(QString fileName)
{
    QString name = "";
    QFile file(fileName);
    if (file.open(QIODevice::ReadOnly)) {
        QString str = file.readAll().trimmed();
        QStringList lst = str.split('\n');
        for (int i = 0; i < lst.count(); i++) {
            QString data = lst.at(i);
            if (data.contains("Icon")) {
                QStringList lstData = data.split("=");
                name = lstData.at(1);
                break;
            }
        }
    }

    file.close();
    return name;
}

QStringList execText(QString fileName, QString fileName1)
{
    QString name = "";
    QFile file(fileName);
    if (file.open(QIODevice::ReadOnly)) {
        QString str = file.readAll().trimmed();
        QStringList lst = str.split('\n');
        for (int i = 0; i < lst.count(); i++) {
            QString data = lst.at(i);
            if (data.contains("Exec")) {
                QStringList lstData = data.split("=");
                name = lstData.at(1);
                name.remove("\n");
                break;
            }
        }
    }

    file.close();

    QProcess process;
    QString cmd = QString("%1 %2").arg(name).arg(fileName1);
    process.start(cmd);
    process.waitForFinished(-1);
    QString output = process.readAllStandardOutput();
    QStringList lst = output.split("\n");
    return lst;
}

 
int main(int argc, char *argv[])
{
    if (argc < 4) {
        return 1;
    }

    if (QString(QLatin1String(argv[1])) == "-d") {
        int flag = checkFile(argv[2]);
        if(flag != 0){
            cout << "file format error" << endl;
            return 1;
        }
    }

    if (argc == 4)
    {
        if (QString(QLatin1String(argv[3])) == "-n") {
            QString name = getName(argv[2]);
            if(name.isEmpty()){
                return 1;
            }
            cout << name.toStdString() << endl;
        } else if (QString(QLatin1String(argv[3])) == "-i") {
            QString Icon = getIcon(argv[2]);
            if(Icon.isEmpty()){
                return 1;
            }
            cout << Icon.toStdString() << endl;
        }
    }

    if (argc >= 5)
    {
        if (QString(QLatin1String(argv[3])) == "-e") {
            QStringList lstData = execText(argv[2], argv[4]);
            if(lstData.isEmpty()){
                return 1;
            }

            for (int i = 0; i < lstData.count(); i++) {
                cout << lstData.at(i).toStdString() << endl;
            }

        }
    }

    return 0;
}

